
package com.joysuch.wwyt.dataperm.spring;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;

import com.joysuch.wwyt.dataperm.spring.listeners.DataDumpAnnotationClassScanListener;
import com.joysuch.wwyt.dataperm.spring.listeners.DataPermAnnotationClassScanListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.stereotype.Component;

/**
 * 利用Spring的类扫描工具，启动阶段，扫描添加了数据权限注解的类
 */
@Component
public class WwytClassScanner implements ApplicationContextAware {

    private static final Logger logger = LoggerFactory.getLogger("datapermission");

    String classPathPattern = "classpath*:com/joysuch/**/*.class";
    private List<ClassScanListener> listeners;

    private ApplicationContext applicationContext;

    public WwytClassScanner() {

    }

    public WwytClassScanner(String classPathPattern) {
        super();
        this.classPathPattern = classPathPattern;
    }

    private void initListeners() {
        listeners = new ArrayList<>();
        listeners.add(new DataPermAnnotationClassScanListener());
        listeners.add(applicationContext.getBean(DataDumpAnnotationClassScanListener.class));
    }

    @PostConstruct
    @Order(10)
    public void scan() throws IOException, ClassNotFoundException {
        initListeners();
        long s = System.currentTimeMillis();
        PathMatchingResourcePatternResolver pathMatchingResourcePatternResolver = new PathMatchingResourcePatternResolver();
        CachingMetadataReaderFactory cachingMetadataReaderFactory = new CachingMetadataReaderFactory();
        Resource[] resources = pathMatchingResourcePatternResolver.getResources(classPathPattern);
        for (Resource resource : resources) {
            MetadataReader reader = cachingMetadataReaderFactory.getMetadataReader(resource);
            String className = reader.getClassMetadata().getClassName();
            Class aClass = Class.forName(className);
            if (listeners != null && listeners.size() > 0) {
                for (ClassScanListener l : listeners) {
                    l.onScanClass(aClass);
                }
            }
        }
        long e = System.currentTimeMillis();
        logger.debug("扫描类花费" + (e - s) + "ms");
    }

    public List<ClassScanListener> getListeners() {
        return listeners;
    }

    public void setListeners(List<ClassScanListener> listeners) {
        this.listeners = listeners;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

}
